package com.example.mallprotal.config;

import com.netflix.client.config.IClientConfig;
import com.netflix.loadbalancer.AbstractLoadBalancerRule;
import com.netflix.loadbalancer.ILoadBalancer;
import com.netflix.loadbalancer.Server;
import com.sun.org.apache.bcel.internal.generic.ILOAD;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import java.util.List;

/**
 * @author 陳樂
 * @version 1.0.0
 * @ClassName IpHashRule.java
 * @Description TODO
 * @createTime 2022年06月14日 22:51:00
 */
public class IpHashRule extends AbstractLoadBalancerRule {

    @Override
    public void initWithNiwsConfig(IClientConfig iClientConfig) {
        //...
    }

    public Server choose(ILoadBalancer lb, Object key) {
        if (lb == null) {
            return null;
        }

        Server server = null;
        while (server == null) {
            //启动的服务列表（单纯使用ribbon时，是不会做心跳检测的）
            List<Server> reachableServers = lb.getReachableServers();
            List<Server> allServers = lb.getAllServers();
            int size = allServers.size();
            if (size == 0) {
                return null;
            }
            int index = ipAddressHash(size);
            server = reachableServers.get(index);
        }
        return server;
    }

    private int ipAddressHash(int serverCount) {
        ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        String remoteAddr = requestAttributes.getRequest().getRemoteAddr();
        int code = Math.abs(remoteAddr.hashCode());
        return code % serverCount;
    }

    @Override
    public Server choose(Object o) {
        return choose(getLoadBalancer(), o);
    }
}
